import time
import threading
import logging
from datetime import datetime

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('auto_control')

class AutoControlService:
    """自动控制服务 - 监控设备状态并自动调整床板"""
    
    def __init__(self, check_interval=2.0):
        """初始化自动控制服务
        
        Args:
            check_interval: 检查间隔时间(秒)
        """
        self.check_interval = check_interval
        self.running = False
        self.thread = None
        self.device_status = {}  # 存储设备最新状态
        self.settings = {
            'ENABLED': True,  # 是否启用自动控制
            'ADJUSTMENTS': {
                'SITTING_UP': {
                    'ENABLED': True,
                    'ANGLE': 50,  # 调整角度
                    'SPEED': 1    # 调整速度(1=慢, 2=正常, 3=快)
                }
            }
        }
        self.device_last_adjusted = {}  # 记录设备最后调整时间
        
    def start(self):
        """启动自动控制服务"""
        if not self.running:
            self.running = True
            self.thread = threading.Thread(target=self._monitor_loop, daemon=True)
            self.thread.start()
            logger.info("✅ 自动控制服务已启动")
            return True
        return False
    
    def stop(self):
        """停止自动控制服务"""
        if self.running:
            self.running = False
            if self.thread:
                self.thread.join(timeout=5.0)
                logger.info("❌ 自动控制服务已停止")
            return True
        return False
    
    def update_device_status(self, device_id, status_data):
        """更新设备状态（从数据处理器调用）
        
        Args:
            device_id: 设备ID
            status_data: 设备状态数据
        """
        # 更新设备状态
        self.device_status[device_id] = status_data
        
        # 仅在自动控制服务运行时处理状态变化
        if self.running and self.settings['ENABLED']:
            # 尝试提取坐起状态
            sitting_up_value = None
            
            # 尝试从不同来源获取 sitting_up 值
            if 'sitting_up' in status_data:
                sitting_up_value = status_data['sitting_up']
            elif 'data' in status_data and isinstance(status_data['data'], dict):
                sitting_up_value = status_data['data'].get('sitting_up')
            elif 'raw_data' in status_data and isinstance(status_data['raw_data'], dict):
                # 从PropertyStatusInfo中查找sitting_up
                property_list = status_data['raw_data'].get('List', {}).get('PropertyStatusInfo', [])
                for prop in property_list:
                    if prop.get('Identifier') == 'sitting_up' and 'Value' in prop:
                        sitting_up_value = prop['Value']
                        break
            
            # 检查是否需要立即调整
            if sitting_up_value is not None and str(sitting_up_value) == '1':
                logger.info(f"📡 检测到设备 {device_id} 坐起状态变化: sitting_up=1")
                self._adjust_for_sitting_up(device_id)
    
    def _monitor_loop(self):
        """监控循环，定期检查所有设备"""
        logger.info("🔄 设备状态监控循环已启动")
        while self.running:
            try:
                self._check_all_devices()
                time.sleep(self.check_interval)
            except Exception as e:
                logger.error(f"❌ 自动控制监控循环出错: {str(e)}")
                time.sleep(5)
    
    def _check_all_devices(self):
        """检查所有设备状态"""
        if not self.settings['ENABLED']:
            return
            
        for device_id, status in list(self.device_status.items()):
            try:
                # 提取坐起状态
                sitting_up_value = None
                
                if isinstance(status, dict):
                    # 直接从状态中查找
                    if 'sitting_up' in status:
                        sitting_up_value = status['sitting_up']
                    # 从数据中查找
                    elif 'data' in status and isinstance(status['data'], dict):
                        sitting_up_value = status['data'].get('sitting_up')
                    # 从原始数据中查找
                    elif 'raw_data' in status and isinstance(status['raw_data'], dict):
                        property_list = status['raw_data'].get('List', {}).get('PropertyStatusInfo', [])
                        for prop in property_list:
                            if prop.get('Identifier') == 'sitting_up' and 'Value' in prop:
                                sitting_up_value = prop['Value']
                                break
                
                # 检查坐起状态
                if sitting_up_value is not None and str(sitting_up_value) == '1':
                    self._adjust_for_sitting_up(device_id)
            except Exception as e:
                logger.error(f"❌ 检查设备 {device_id} 状态时出错: {str(e)}")
    
    def _adjust_for_sitting_up(self, device_id):
        """处理坐起状态
        
        Args:
            device_id: 设备ID
        """
        if not self.running or not self.settings['ENABLED']:
            return
            
        # 确保自动坐起调整功能已启用
        if not self.settings['ADJUSTMENTS']['SITTING_UP']['ENABLED']:
            logger.debug(f"⏭️ 自动坐起调整功能已禁用")
            return
            
        # 防抖处理，防止短时间内重复触发
        current_time = time.time()
        last_adjusted = self.device_last_adjusted.get('Spark', 0)
        
        if current_time - last_adjusted < 10:  # 10秒内只允许触发一次
            logger.debug(f"⏭️ 最近已调整，跳过自动控制")
            return
        
        # 获取目标角度和速度
        target_angle = self.settings['ADJUSTMENTS']['SITTING_UP']['ANGLE']
        target_speed = self.settings['ADJUSTMENTS']['SITTING_UP']['SPEED']
        
        # 安全角度检查
        target_angle = min(max(target_angle, 0), 90)
        target_speed = min(max(target_speed, 1), 3)
        
        # 记录调整时间 - 使用Spark作为设备标识
        self.device_last_adjusted['Spark'] = current_time
        
        logger.info(f"🛏️ 检测到坐起状态，自动调整床板到 {target_angle}° (速度: {target_speed})")
        
        # 调用床板控制函数
        try:
            # 导入命令发送器
            from device_controller import command_sender
            
            # 硬编码使用Spark设备
            device_name = "Spark"
            product_key = "k29cquyln1r"
            
            # 发送控制命令
            logger.info(f"发送床板控制命令: 设备={device_name}, 产品密钥={product_key}, 角度={target_angle}, 速度={target_speed}")
            success, message = command_sender.send_bed_command(
                device_name=device_name,
                product_key=product_key,
                angle=target_angle,
                speed_level=target_speed
            )
            
            if success:
                logger.info(f"✅ 自动调整床板成功: {target_angle}° (速度: {target_speed})")
                return True
            else:
                logger.error(f"❌ 自动调整床板失败: {message}")
        except Exception as e:
            logger.error(f"❌ 自动调整床板时出错: {str(e)}")
            
        return False
        
    def get_status(self):
        """获取服务状态信息"""
        return {
            "running": self.running,
            "settings": self.settings,
            "device_count": len(self.device_status),
            "last_check": datetime.now().isoformat()
        }
        
    def update_settings(self, new_settings):
        """更新服务设置
        
        Args:
            new_settings: 新的设置字典
        """
        if isinstance(new_settings, dict):
            # 更新主设置
            if 'ENABLED' in new_settings:
                self.settings['ENABLED'] = bool(new_settings['ENABLED'])
                
            # 更新调整设置
            if 'ADJUSTMENTS' in new_settings and isinstance(new_settings['ADJUSTMENTS'], dict):
                for key, value in new_settings['ADJUSTMENTS'].items():
                    if key in self.settings['ADJUSTMENTS'] and isinstance(value, dict):
                        self.settings['ADJUSTMENTS'][key].update(value)
                        
            logger.info(f"⚙️ 自动控制服务设置已更新: {self.settings}")
            return True
        return False
    
    def handle_sitting_up_detected(self, device_id):
        """立即处理检测到的起身状态
        
        Args:
            device_id: 设备ID
        """
        logger.info(f"🚨 立即处理起身检测: 设备 {device_id}")
        return self._adjust_for_sitting_up(device_id)

# 创建全局单例实例
auto_control_service = AutoControlService()
